package cn.core.act.service.impl;

import cn.core.act.eo.ActProcess;
import cn.core.act.eo.ActProcessChart;
import cn.core.act.mapper.ActProcessChartMapper;
import cn.core.act.mapper.ActProcessMapper;
import cn.core.act.qo.ActProcessChartQO;
import cn.core.act.qo.ActProcessQO;
import cn.core.act.service.intf.IActProcessChartService;
import cn.core.act.vo.ActProcessChartVO;
import cn.core.tool.exception.CoreException;
import cn.core.tool.util.CoreTool;
import cn.core.tool.util.Paging;
import cn.core.tool.util.Param;
import lombok.extern.log4j.Log4j2;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collection;

/**
 * 流程图 服务实现
 */
@Log4j2
@Primary
@Service
public class ActProcessChartServiceImpl implements IActProcessChartService {

  @Resource
  private ActProcessChartMapper actProcessChartMapper;

  @Resource
  private ActProcessMapper actProcessMapper;

  @Resource
  private RepositoryService repositoryService;

  @Override
  @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
  public ActProcessChart save(ActProcessChart eo) throws Exception {
    try {
      if (CoreTool.isNullEo(eo)) {
        throw new CoreException(CoreException.E_PARAM_ERR);
      }
      eo.setId(CoreTool.getUUID32());
      ActProcess actProcess = actProcessMapper.pk(new ActProcessQO().setId(eo.getFkid()));
      if (CoreTool.isNullEo(actProcess)) {
        throw new CoreException(CoreException.E_PARAM_ERR);
      }
      Deployment deployment = repositoryService.createDeployment().addString(actProcess.getProcessKey() + ".bpmn20.xml", eo.getProcessChartContent()).deploy();
      eo.setDeploymentId(deployment.getId());
      ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(eo.getDeploymentId()).singleResult();
      eo.setProcessDefinitionId(processDefinition.getId());
      eo.setProcessChartName(processDefinition.getResourceName());
      eo.setProcessVersions(new Integer(processDefinition.getVersion()).longValue());
      actProcessChartMapper.save(eo);
      return eo;
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  @Override
  @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
  public Collection<ActProcessChart> saveBatch(Collection<ActProcessChart> eos) throws Exception {
    try {
      if (CoreTool.isEmpty(eos)) {
        throw new CoreException(CoreException.E_PARAM_ERR);
      }
      for (ActProcessChart eo : eos) {
        if (CoreTool.isNullEo(eo)) {
          throw new CoreException(CoreException.E_PARAM_ERR);
        }
        eo.setId(CoreTool.getUUID32());
      }
      actProcessChartMapper.saveBatch(new Paging<>(), eos);
      return eos;
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  @Override
  @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
  public ActProcessChart update(ActProcessChart eo) throws Exception {
    try {
      if (CoreTool.isNullEo(eo) || CoreTool.isNullStr(eo.getId())) {
        throw new CoreException(CoreException.E_PARAM_ERR);
      }
      ActProcessChart oeo = actProcessChartMapper.pk(new ActProcessChartQO().setId(eo.getId()));
      if (CoreTool.isNullEo(oeo)) {
        throw new CoreException(CoreException.E_PARAM_ERR);
      }
//      if (eo.getVersions() != null ? !eo.getVersions().equals(oeo.getVersions()) : oeo.getVersions() != null ? true : false) {
//        throw new CoreException(CoreException.E_VERSIONS_ERR);
//      }
      repositoryService.deleteDeployment(oeo.getDeploymentId());
      ActProcess actProcess = actProcessMapper.pk(new ActProcessQO().setId(eo.getFkid()));
      if (CoreTool.isNullEo(actProcess)) {
        throw new CoreException(CoreException.E_PARAM_ERR);
      }
      Deployment deployment = repositoryService.createDeployment().addString(actProcess.getProcessKey() + ".bpmn20.xml", eo.getProcessChartContent()).deploy();
      eo.setDeploymentId(deployment.getId());
      ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(eo.getDeploymentId()).singleResult();
      eo.setProcessDefinitionId(processDefinition.getId());
      eo.setProcessChartName(processDefinition.getResourceName());
      eo.setProcessVersions(new Integer(processDefinition.getVersion()).longValue());
      actProcessChartMapper.update(eo);
      return eo;
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  @Override
  @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
  public Collection<ActProcessChart> updateBatch(Collection<ActProcessChart> eos) throws Exception {
    try {
      if (CoreTool.isEmpty(eos)) {
        throw new CoreException(CoreException.E_PARAM_ERR);
      }
      for (ActProcessChart eo : eos) {
        if (CoreTool.isNullEo(eo) || CoreTool.isNullStr(eo.getId())) {
          throw new CoreException(CoreException.E_PARAM_ERR);
        }
        ActProcessChart oeo = actProcessChartMapper.pk(new ActProcessChartQO().setId(eo.getId()));
        if (CoreTool.isNullEo(oeo)) {
          throw new CoreException(CoreException.E_PARAM_ERR);
        }
//        if (eo.getVersions() != null ? !eo.getVersions().equals(oeo.getVersions()) : oeo.getVersions() != null ? true : false) {
//          throw new CoreException(CoreException.E_VERSIONS_ERR);
//        }
      }
      actProcessChartMapper.updateBatch(new Paging<>(), eos);
      return eos;
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  @Override
  @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
  public void remove(ActProcessChart eo) throws Exception {
    try {
      if (CoreTool.isNullEo(eo) || CoreTool.isNullStr(eo.getId())) {
        throw new CoreException(CoreException.E_PARAM_ERR);
      }
      actProcessChartMapper.remove(eo);
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  @Override
  @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
  public void removeBatch(Collection<ActProcessChart> eos) throws Exception {
    try {
      if (CoreTool.isEmpty(eos)) {
        throw new CoreException(CoreException.E_PARAM_ERR);
      }
      for (ActProcessChart eo : eos) {
        if (CoreTool.isNullEo(eo) || CoreTool.isNullStr(eo.getId())) {
          throw new CoreException(CoreException.E_PARAM_ERR);
        }
      }
      for (ActProcessChart eo : eos) {
        ActProcessChart actProcessChart = actProcessChartMapper.pk(new ActProcessChartQO().setId(eo.getId()));
        if (CoreTool.isNotNullEo(actProcessChart)) {
          repositoryService.deleteDeployment(actProcessChart.getDeploymentId());
        }
      }
      actProcessChartMapper.removeBatch(eos);
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  @Override
  public Long count(ActProcessChartQO qo) throws Exception {
    try {
      return actProcessChartMapper.count(qo);
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  @Override
  public ActProcessChart pk(ActProcessChartQO qo) throws Exception {
    try {
      if (CoreTool.isNullEo(qo) || CoreTool.isNullStr(qo.getId())) {
        throw new CoreException(CoreException.E_PARAM_ERR);
      }
      return actProcessChartMapper.pk(qo);
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  @Override
  public Collection<ActProcessChart> query(ActProcessChartQO qo) throws Exception {
    try {
      return actProcessChartMapper.query(qo);
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  @Override
  public Paging<ActProcessChart> paging(Param<ActProcessChartQO> param) throws Exception {
    try {
      if (CoreTool.isNullEo(param)) {
        throw new CoreException(CoreException.E_PARAM_ERR);
      }
      if (param.getPage() < 1 || param.getRows() < 1) {
        throw new CoreException(CoreException.E_PAGING_PARAM_ERR);
      }
      Paging<ActProcessChart> paging = new Paging<>(param);
      if (CoreTool.isEmpty(param.getData()) || CoreTool.isNullEo(param.get())) {
        Long count = actProcessChartMapper.count(null);
        paging.setCount(count);
        if (count > 0) {
          if (count <= paging.getOffset()) {
            throw new CoreException(CoreException.E_PAGING_PARAM_ERR);
          }
          paging.setData(actProcessChartMapper.paging(paging, null));
        }
      } else {
        Long count = actProcessChartMapper.count(param.get());
        paging.setCount(count);
        if (count > 0) {
          if (count <= paging.getOffset()) {
            throw new CoreException(CoreException.E_PAGING_PARAM_ERR);
          }
          paging.setData(actProcessChartMapper.paging(paging, param.get()));
        }
      }
      return paging;
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  @Override
  public Long countVo(ActProcessChartQO qo) throws Exception {
    try {
      return actProcessChartMapper.countVo(qo);
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  @Override
  public ActProcessChartVO pkVo(ActProcessChartQO qo) throws Exception {
    try {
      if (CoreTool.isNullEo(qo) || CoreTool.isNullStr(qo.getId())) {
        throw new CoreException(CoreException.E_PARAM_ERR);
      }
      return actProcessChartMapper.pkVo(qo);
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  @Override
  public Collection<ActProcessChartVO> queryVo(ActProcessChartQO qo) throws Exception {
    try {
      return actProcessChartMapper.queryVo(qo);
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  @Override
  public Paging<ActProcessChartVO> pagingVo(Param<ActProcessChartQO> param) throws Exception {
    try {
      if (CoreTool.isNullEo(param)) {
        throw new CoreException(CoreException.E_PARAM_ERR);
      }
      if (param.getPage() < 1 || param.getRows() < 1) {
        throw new CoreException(CoreException.E_PAGING_PARAM_ERR);
      }
      Paging<ActProcessChartVO> paging = new Paging<>(param);
      if (CoreTool.isEmpty(param.getData()) || CoreTool.isNullEo(param.get())) {
        Long count = actProcessChartMapper.countVo(null);
        paging.setCount(count);
        if (count > 0) {
          if (count <= paging.getOffset()) {
            throw new CoreException(CoreException.E_PAGING_PARAM_ERR);
          }
          paging.setData(actProcessChartMapper.pagingVo(paging, null));
        }
      } else {
        Long count = actProcessChartMapper.countVo(param.get());
        paging.setCount(count);
        if (count > 0) {
          if (count <= paging.getOffset()) {
            throw new CoreException(CoreException.E_PAGING_PARAM_ERR);
          }
          paging.setData(actProcessChartMapper.pagingVo(paging, param.get()));
        }
      }
      return paging;
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

}
